package com.geeklan.smart.ui.network;

import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.CountDownTimer;
import android.os.Handler;
import android.os.Message;
import android.provider.Settings;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
import androidx.lifecycle.ViewModelProvider;

import com.geeklan.base.base.BaseActivity;
import com.geeklan.base.utils.MLog;
import com.geeklan.smart.R;
import com.geeklan.smart.common.Constants;
import com.geeklan.smart.data.model.DeviceStatusResponse;
import com.geeklan.smart.data.remote.NetworkConstant;
import com.geeklan.smart.data.remote.tcp.Cmd;
import com.geeklan.smart.data.remote.tcp.TaskCenter;
import com.geeklan.smart.data.repository.device.DeviceRepository;
import com.geeklan.smart.databinding.ActivityDeviceNetworkTwoBinding;
import com.geeklan.smart.ui.viewmodel.device.DeviceViewModel;
import com.geeklan.smart.ui.viewmodel.device.DeviceViewModelFactory;
import com.geeklan.smart.utils.Base64Utils;
import com.geeklan.smart.utils.CopyUtils;
import com.geeklan.smart.utils.WifiUtils;

import org.json.JSONObject;

import java.io.IOException;
import java.util.List;

public class DeviceNetworkTwoActivity extends BaseActivity<ActivityDeviceNetworkTwoBinding> implements TaskCenter.OnReceiveCallbackBlock{
    private static final int SEND_CMD_0 = 0;
    private static final int SEND_CMD_1 = 1;
    private static final int SEND_CMD_2 = 2;
    private static final int SEND_CMD_3 = 3;
    private static final int SEND_CMD_4 = 4;
    private static final int DISMISS_LOADING = 5;
    private static final int LOADING = 8;
    private static final int GET_DEVICE_STATUS = 6;
    private static final int BIND_DEVICE = 7;
    private static final int FINISH = 9;
    public static String WIFI_SSID = "WIFI_SSID";
    public static String WIFI_PWD = "WIFI_PWD";

    private String ssid, pwd;
    private DeviceViewModel deviceViewModel;
    @Override
    protected ActivityDeviceNetworkTwoBinding initBinding() {
        return ActivityDeviceNetworkTwoBinding.inflate(getLayoutInflater());
    }

    @Override
    protected void initData() {
        ssid = getIntent().getStringExtra(WIFI_SSID);
        pwd = getIntent().getStringExtra(WIFI_PWD);
        deviceViewModel = new ViewModelProvider(this, new DeviceViewModelFactory(new DeviceRepository())).get(DeviceViewModel.class);

        //查询设备在线状态
        deviceViewModel.getDeviceStatusLiveData().observe(this, apiResponse -> {
            List<DeviceStatusResponse.DataDTO> data = apiResponse.getData();
            if(data.isEmpty() || data.get(0).getOnlineStatus() != 1) {
                MLog.i("设备不在线");
                handler.sendEmptyMessageDelayed(GET_DEVICE_STATUS, 2000);
            }else{
                MLog.i("设备在线");
                timer.cancel();
                handler.sendEmptyMessageDelayed(BIND_DEVICE, 200);
            }
        });
        deviceViewModel.getDeviceStatusErrorLiveData().observe(this, s -> {
            MLog.i("获取设备状态接口异常");
            handler.sendEmptyMessageDelayed(GET_DEVICE_STATUS, 2000);
        });


        //绑定设备
        deviceViewModel.getBindDeviceLiveData().observe(this, apiResponse -> {
            handler.sendEmptyMessage(DISMISS_LOADING);
            Toast.makeText(this, R.string.binding_success,Toast.LENGTH_SHORT).show();
            ConnectSuccessActivity.startActivity(DeviceNetworkTwoActivity.this);
            finish();
        });
        deviceViewModel.getBindErrorLiveData().observe(this, s -> {
            handler.sendEmptyMessage(DISMISS_LOADING);
            Toast.makeText(this,s,Toast.LENGTH_SHORT).show();
        });

        TaskCenter.sharedCenter().setDisconnectedCallback(new TaskCenter.OnServerDisconnectedCallbackBlock() {
            @Override
            public void callback(IOException e) {
                MLog.i("******** tcp 断开连接\n");
                handler.sendEmptyMessage(DISMISS_LOADING);
            }
        });
        TaskCenter.sharedCenter().setConnectedCallback(new TaskCenter.OnServerConnectedCallbackBlock() {
            @Override
            public void callback() {
                MLog.i("******** tcp 连接成功");
                handler.sendEmptyMessageDelayed(SEND_CMD_0, 500);
            }
        });
        TaskCenter.sharedCenter().setReceivedCallback(this);
    }

    CountDownTimer timer = new CountDownTimer(30000, 1000) {
        public void onTick(long millisUntilFinished) {

        }
        public void onFinish() {
            handler.sendEmptyMessage(FINISH);
        }
    };

    private String[] getRequiredPermissions() {
        return new String[]{
                Manifest.permission.ACCESS_FINE_LOCATION,
                Manifest.permission.ACCESS_WIFI_STATE,
                Manifest.permission.CHANGE_WIFI_STATE
        };
    }

    private boolean checkPermissions() {
        for (String permission : getRequiredPermissions()) {
            int permissionCheck = ContextCompat.checkSelfPermission(this, permission);
            if (permissionCheck != PackageManager.PERMISSION_GRANTED) {
                return false;
            }
        }
        return true;
    }


    @Override
    protected void initView() {
        mBinding.tvNext.setOnClickListener(v -> {
            if (!checkPermissions()) {
                ActivityCompat.requestPermissions(this, getRequiredPermissions(), PERMISSION_REQ_ID);
            } else {
                connectTcp();
            }
        });
        mBinding.tvGoConnect.setOnClickListener(v -> {
            Intent intent = new Intent(Settings.ACTION_WIFI_SETTINGS);
            startActivity(intent);
        });
        mBinding.tvCopy.setOnClickListener(v -> {
            CopyUtils.copyToClipboard(this,mBinding.tvPwd.getText().toString());
        });
        mBinding.ivBack.setOnClickListener(v -> {
            finish();
        });
    }

    @Override
    public void onPermissionsResultSuccess() {
        if (checkPermissions()) {
            connectTcp();
        }
    }

    private void connectTcp(){
        String ssid = WifiUtils.getConnectedSSID(this);
        MLog.i("******** tcp 当前连接的wifi :" + ssid);
        if (ssid!= null && ssid.startsWith("miaomojo")) {
            handler.sendEmptyMessage(LOADING);
            TaskCenter.sharedCenter().connect(Constants.TARGET_DEVICE_IP,Constants.TARGET_PORT);
        }else {
            Toast.makeText(this, getString(R.string.connect_device_wifi),Toast.LENGTH_SHORT).show();
        }
    }

    @Override
    public void onPermissionsResultFail() {
        Toast.makeText(this, R.string.permission_denied, Toast.LENGTH_SHORT).show();
    }

    @Override
    protected void onApplyWindowInsets() {
        ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
            Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
            v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
            return insets;
        });
    }

    @Override
    public void networkStatus(boolean isConnected) {
        if(isConnected){
        }
    }

    @Override
    public void networkType(int type) {

    }

    public static void startActivity(Context context, String ssid, String pwd) {
        Intent intent = new Intent(context, DeviceNetworkTwoActivity.class);
        intent.putExtra(WIFI_SSID, ssid);
        intent.putExtra(WIFI_PWD, pwd);
        context.startActivity(intent);
    }

    Handler handler = new Handler(new Handler.Callback() {
        @Override
        public boolean handleMessage(@NonNull Message msg) {
            int what = msg.what;
            if (what == SEND_CMD_0) {
                TaskCenter.sharedCenter().send(Cmd.cmd0.getBytes());
            } else if (what == SEND_CMD_1) {

            } else if (what == SEND_CMD_2) {
                TaskCenter.sharedCenter().send(String.format(Cmd.cmd2, ssid, pwd).getBytes());
            } else if (what == SEND_CMD_3) {
                TaskCenter.sharedCenter().send(String.format(Cmd.cmd3, "host", "1", "0", Base64Utils.stringToBase64(NetworkConstant.BASE_URL)).getBytes());
            }  else if (what == SEND_CMD_4) {
                TaskCenter.sharedCenter().send(Cmd.cmd4.getBytes());
            } else if (what == LOADING) {
                loading(R.string.network_pairing);
            } else if (what == DISMISS_LOADING) {
                dismiss();
            } else if (what == GET_DEVICE_STATUS) {
                deviceViewModel.getDeviceById(mac);
            } else if (what == BIND_DEVICE) {
                deviceViewModel.bindUserDevice(mac);
            } else if (what == FINISH) {
                handler.removeMessages(GET_DEVICE_STATUS);
                ConnectFailActivity.startActivity(DeviceNetworkTwoActivity.this);
                finish();
            }
            return false;
        }
    });

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if(TaskCenter.sharedCenter().isConnected()) {
            TaskCenter.sharedCenter().disconnect();
        }
    }

    private String mac;

    @Override
    public void callback(String receicedMessage) {
        try {
            if (receicedMessage != null) {
                JSONObject jsonObject = new JSONObject(receicedMessage);
                // 获取 cmd 值
                int cmd = jsonObject.getInt("cmd");
                if (cmd == 0) {
                    // 获取 data 对象
                    JSONObject dataObject = jsonObject.getJSONObject("data");
                    // 获取 mac 值
                    mac = dataObject.getString("mac");
                    handler.sendEmptyMessageDelayed(SEND_CMD_2, 1000);
                }else if (cmd == 2) {
                    handler.sendEmptyMessageDelayed(SEND_CMD_3, 1000);
                } else if (cmd == 3) {
                    handler.sendEmptyMessageDelayed(SEND_CMD_4, 1000);
                } else if (cmd == 4) {
                    handler.sendEmptyMessageDelayed(GET_DEVICE_STATUS, 5000);
                    timer.start();
                }
            }
        } catch (Exception e) {
            Toast.makeText(DeviceNetworkTwoActivity.this, R.string.unknown_error,Toast.LENGTH_SHORT).show();
        }
    }
}